import encryptPwd from './encrypt-pwd'
import uniToken from './uni-token'
import {
  userCollection,
  log,
  getConfig,
  friendlyDate
} from '../share/index'
import loginCheck from '../common/login-check'

const db = uniCloud.database()
async function login ({ username, password, queryField = [] }) {
  const dbCmd = db.command
  const query = []
  if (!queryField || !queryField.length) {
    queryField = ['username']
  }
  const extraCond = {
    email: {
      email_confirmed: 1
    },
    mobile: {
      mobile_confirmed: 1
    }
  }
  queryField.forEach(item => {
    query.push({
      [item]: username,
      ...extraCond[item]
    })
  })
  const userInDB = await userCollection.where(dbCmd.or(...query)).limit(1).get()
  const clientIP = __ctx__.CLIENTIP
  const {
    passwordErrorLimit,
    passwordErrorRetryTime
  } = getConfig()

  log('userInDB:', userInDB)

  if (userInDB && userInDB.data && userInDB.data.length > 0) {
    const userMatched = userInDB.data[0]
    const pwdInDB = userMatched.password

    // 根据ip地址，密码错误次数过多，锁定登录
    let loginIPLimit = userMatched.login_ip_limit || []
    // 清理无用记录
    loginIPLimit = loginIPLimit.filter(item => item.last_error_time > Date.now() - passwordErrorRetryTime * 1000)
    let currentIPLimit = loginIPLimit.find(item => item.ip === clientIP)
    if (currentIPLimit && currentIPLimit.error_times >= passwordErrorLimit) {
      return {
        code: 10103,
        msg: `密码错误次数过多，请${friendlyDate(currentIPLimit.last_error_time + passwordErrorRetryTime * 1000)}再试。`
      }
    }
    if (encryptPwd(password) === pwdInDB) {
      try {
        const loginCheckRes = await loginCheck(userMatched)
        if (loginCheckRes.code !== 0) {
          return loginCheckRes
        }
        const tokenList = loginCheckRes.user.token

        log('开始修改最后登录时间')

        const {
          token,
          tokenExpired
        } = uniToken.createToken(userMatched)
        log('token', token)
        tokenList.push(token)
        const upRes = await userCollection.doc(userMatched._id).update({
          last_login_date: new Date().getTime(),
          last_login_ip: clientIP,
          token: tokenList,
          login_ip_limit: loginIPLimit
        })

        log('upRes', upRes)

        return {
          code: 0,
          token,
          uid: userMatched._id,
          username: username,
          msg: '登录成功',
          tokenExpired
        }
      } catch (e) {
        log('写入异常：', e)
        return {
          code: 90001,
          msg: '数据库写入异常'
        }
      }
    } else {
      if (!currentIPLimit) {
        currentIPLimit = {
          ip: clientIP,
          error_times: 1,
          last_error_time: Date.now()
        }
        loginIPLimit.push(currentIPLimit)
      } else {
        currentIPLimit.error_times++
        currentIPLimit.last_error_time = Date.now()
      }
      await userCollection.doc(userMatched._id).update({
        login_ip_limit: loginIPLimit
      })
      return {
        code: 10102,
        msg: '密码错误'
      }
    }
  } else {
    return {
      code: 10101,
      msg: '用户不存在'
    }
  }
}

export default login
